Density Plots: Distribution of Attendance Rates by Safety Rating

ggplot(subset(filter(combined_1617, Primary_Category == "ES"), !is.na(School_Survey_Safety)), aes(x=Student_Attendance_Year_2_Pct, color = School_Survey_Safety, fill=School_Survey_Safety)) +
  geom_density() + 
  scale_fill_viridis(guide = FALSE, discrete=TRUE, option='magma', begin=0.2, end=0.85) + 
  scale_color_viridis(guide = FALSE, discrete=TRUE, option='magma', begin=0.2, end=0.85) + 
  facet_wrap(~ School_Survey_Safety, ncol=1) + 
  labs(title = "Attendance tends to be higher at schools where students feel safe",
       subtitle = "Distribution of elementary school attendance rates by safety ratings*",
       x = "Student Attendance Rate (Percents)",
       y = "Density",
       caption = "Source: Chicago Public Schools - School Progress Reports SY1617\n *Safety ratings based on student survey") +
  mytheme

Not every student feels safe at school. The 5 Essentials Survey administered annually to CPS students measures student’ perception of safety, rating each school on a scale of “very weak” to “very strong.” Results from the 2016-2017 school year suggest that schools with weaker safety ratings also face lower student attendance.

Density Plots: Distribution of Attainment Percentiles by Safety Rating

ggplot(subset(filter(combined_1617, Primary_Category == "ES"), !is.na(School_Survey_Safety)), aes(x=Attainment_Reading_Pct_ES, color = School_Survey_Safety, fill=School_Survey_Safety)) +
  geom_density() + 
  scale_fill_viridis(guide = FALSE, discrete=TRUE, option='magma', begin=0.2, end=0.85) + 
  scale_color_viridis(guide = FALSE, discrete=TRUE, option='magma', begin=0.2, end=0.85) + 
  facet_wrap(~ School_Survey_Safety, ncol=1) + 
  labs(title = "Attainment tends to be higher at schools where students feel safe",
       subtitle = "Distribution of elementary school reading attainment percentiles by safety ratings*",
       x = "Student Reading Attainment (Percentile of National Average)",
       y = "Density",
       caption = "Source: Chicago Public Schools - School Progress Reports SY1617\n *Safety ratings based on student survey") +
  mytheme

Students’ sense of school safety not only affects their attendance, but also their performance. Elementary schools with weak safety survey ratings performed worse on standardized reading tests than those with strong safety ratings. Whether directly or indirectly, unsafe school environments could be a contributing factor to negative student outcomes.

Boxplot: Crimes in Vicinity by Safety Rating

ggplot(subset(combined_1617_crimes, !is.na(School_Survey_Safety)), aes(x=School_Survey_Safety, y=num_crimes_16, fill=School_Survey_Safety)) +
  scale_fill_viridis(option='magma', discrete=TRUE, begin=0.2, end=0.85) + 
  geom_boxplot() + 
  guides(fill=FALSE) + 
  labs(title = "Students feel more unsafe at school in high-crime neighborhoods",
       subtitle = "Schools with weaker safety ratings face higher number of crimes \nwithin 1 mile radius of campus",
       x = "Safety Rating*",
       y = "Number of Crimes in School Vicinity",
       caption = "Source: Chicago Public Schools - School Progress Reports SY1617\n Chicago Police Department - Crimes 2016
        \n *Safety ratings based on student survey") + 
  mytheme

Many instances of crime happen close to school grounds. On average, ~4000 crimes were reported within a 1 mile radius of each CPS school in 2016. Schools with weaker safety ratings had more crime incidents reported within their vicinity. These nearby crimes rates could influence students’ perception of safety at their schools.

Scatter: Percent Low Income Students vs. Crimes in Vicinity

profile <- mutate(profile, perc_lowincome = Student_Count_Low_Income / Student_Count_Total)
subset(combined_1617_crimes, !is.na(School_Survey_Safety)) %>%
  merge(profile, by="School_ID") %>%
  ggplot(aes(x = perc_lowincome, y = num_crimes_16)) +
    geom_point(aes(color = School_Survey_Safety), alpha=0.5) +
    geom_smooth(model = lm) + 
    scale_x_continuous(labels = scales::percent) + 
    scale_color_viridis(name="Safety Rating*", option='magma', begin=0.2, end=0.85, discrete=TRUE) + 
    labs(title = "Low income students attend schools in highest-crime neighborhoods ",
         subtitle = "Schools with higher percent of low income students see higher number of \ncrimes wtihin 1 mile radius",
         x = "Percent Low Income Students",
         y = "Number of Crimes in School Vicinity",
         caption = "Source: Chicago Public Schools - School Progress Reports SY1617\n Chicago Police Department - Crimes 2016
          \n *Safety ratings based on student survey") + 
    mytheme  + theme(legend.position="bottom")

Low-income students are attending the schools with the highest rates of nearby crime. The steep slope at the rightmost side of curve fitted to the above scatterplot suggests that the schools surrounded by the most crime also have the highest proportion of low-income students.

Heat Map: Perception of School Safety by Neighborhoods

combined_1617 %>%
  subset(!is.na(School_Survey_Safety) & !is.na(Neighborhood)) %>%
  group_by(Neighborhood, School_Survey_Safety) %>%
  summarize(num_schools=n(), na.rm = TRUE) %>% 
  mutate(prop_schools = num_schools/sum(num_schools)) %>%
  ggplot(aes(x=School_Survey_Safety, y=Neighborhood, fill=prop_schools)) + 
  geom_tile() + 
  scale_fill_distiller(name = 'Proportion of Schools\n in Neighborhood\n', palette='Greys', direction=1) + 
  labs(title = "Students' perception of school safety varies between neighborhoods",
       x = "Safety Rating*",
       y = "Neighborhood",
       caption = "Source: Chicago Public Schools - School Progress Reports SY1617\n *Safety ratings based on student survey") + 
  mytheme + theme(legend.position="bottom")

Who are these students who are most affected by these unsafe school environments? Where do they live? This preliminary heat map suggests that school safety perceptions vary by neighborhood. In the next few visualizations, we will begin to explore this topic from a geographical context.

Map: School Locations, Safety Ratings, and Crimes

chicago <- ggmap(get_map(location = bbox(school_locations), source='stamen', maptype='toner-lite', color='bw'))

chicago + 
  geom_point(data=combined_1617_crimes %>% subset(!is.na(School_Survey_Safety)), aes(long, lat,  color=School_Survey_Safety, size=num_crimes_16, alpha=0.3)) + 
  scale_alpha(guide=FALSE) + 
  scale_color_viridis(name = "Safety Rating*", option="magma", discrete=TRUE, begin=0.2, end=0.85)+
  scale_size(name='Number of Crimes within \n1 Mile in 2016') +
  coord_equal() + 
  labs(title = "Students' perception of safety varies across the city",
       caption = "Source: Chicago Public Schools - School Progress Reports SY1617\n Chicago Police Department - Crimes 2016
       \n *Safety ratings based on student survey") + 
  mytheme + 
  theme(axis.title=element_blank(), axis.text=element_blank(), axis.ticks=element_blank())

Although students’ perception of safety varies across the city, the schools where students feel most unsafe are located in the south and west sides of Chicago. There appears to be a cluster of schools in west Chicago with high surrounding crime rates. Surprisingly, some schools in that cluster received high safety ratings from their students. Factors other than crime rates may contribute to students’ feelings of safety at school.

Map: Crime and Safe Passage Routes

safe_passage <- readOGR(dsn=path.expand("../cps_data/Chicago Public Schools - Safe Passage Routes SY1617"), layer="geo_export_05e1123e-61d4-4f97-b8c6-1a8223234e8c")
## OGR data source with driver: ESRI Shapefile 
## Source: "../cps_data/Chicago Public Schools - Safe Passage Routes SY1617", layer: "geo_export_05e1123e-61d4-4f97-b8c6-1a8223234e8c"
## with 100 features
## It has 4 fields
safe_passage_df <- tidy(safe_passage, region="rt_num")

chicago + 
  geom_line(data = safe_passage_df, aes(long, lat, group=group), size=1.2) + 
  geom_point(data=combined_1617_crimes, aes(long, lat, color=crime_quartile), alpha=0.4, size=3) + 
  coord_equal() + 
  scale_alpha(guide=FALSE) + 
  scale_color_viridis(option='plasma', direction=-1, discrete=TRUE, name = "Number of Crimes within \n1 Mile in 2016 (Quartile)") + 
  labs(title = "Safe passage routes cover some schools in high-crime\nneighborhoods, but not all ",
       caption = "Source: Chicago Public Schools - School Progress Reports SY1617\n Chicago Police Department - Crimes 2016\nChicago Public Schools - Safe Passage Routes SY1617
       \n *Safety ratings based on student survey") + 
  mytheme + 
  theme(axis.title=element_blank(), axis.text=element_blank(), axis.ticks=element_blank())

Chicago Public Schools initiated the Safe Passage program in 2013 to protect students from street violence. Trained adults are stationed along Safe Passage routes to guide students to and from school each day. These safe passage routes cover many of the schools in the top quartile in terms of the number of nearby crimes in 2016. However, there are still many schools in high-crime areas that are not covered by this program.